package com.weavernorth.util;
/**  
 * @Title:  SoapUtil.java
 * @Package util.webservice
 * @Description:webservice接口调用工具
 * @author CuiZiHua
 * @date  2017年9月15日 上午10:35:38
 * @version V1.0  
 * Update Logs:
 * ****************************************************
 * Name:
 * Date:
 * Description:
 ******************************************************
 */


import org.apache.commons.io.IOUtils;
import org.dom4j.*;
import weaver.general.BaseBean;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;


//import weaver.general.BaseBean;

/**
 * @ClassName: SoapUtil
 * @Description:webservice接口调用工具
 * @author 
 * @date 2017年9月15日 上午10:35:38
 * 
 */
public class JdeUtil
{

    /**
     * @throws Exception
     * @Title: executeCall
     * @Description:执行s交互
     * @author CuiZiHua
     * @param soapXML
     * @param url
     * @param sOAPAction
     * @return
     * @throws
     */
    public String executeCall(String soapXML, String httpUrl, String SOAPAction)
            throws Exception
    {
    	new BaseBean().writeLog("调试");
        // 响应soap信息
        String responseXML = "";
        // 判断是否有SOAPAction选择执行不同的调用方式

        if (SOAPAction.length() <= 0)
        {// 没有SOAPAction
            responseXML = executeCallWithNoAction(soapXML, httpUrl);
        }
        else
        {
            // 有SOAPAction
            responseXML = executeCallWithAction(soapXML, httpUrl, SOAPAction);
        }
        return responseXML;
    }

    /**
     * @throws Exception
     * @Title: executeCallWithAction
     * @Description:需要SOAPAction的方式 所有的wsdl均可使用该方式
     * @author CuiZiHua
     * @param soapXML
     * @param httpUrl
     * @param SOAPAction
     * @return
     * @throws
     */
    private String executeCallWithAction(String soapXML, String httpUrl,
            String SOAPAction) throws Exception
    { // 响应soap信息
        String responseXML = new String();

        // 拼装soap请求报文

        StringBuilder soapHeader = new StringBuilder();
        soapHeader.append(soapXML);
        //new BaseBean().writeLog(soapHeader + "soapHeader");

        // 设置soap请求报文的相关属性
        String url = httpUrl;
        URL u = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        // post请求不能使用缓存
        conn.setUseCaches(false);
        conn.setDefaultUseCaches(false);
        // conn.setRequestProperty("Host", "hrsit1.haidilao.com:8000");//
        conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
        conn.setRequestProperty("Content-Length",
                String.valueOf(soapHeader.length()));
        conn.setRequestProperty("SOAPAction", SOAPAction);
        conn.setRequestMethod("POST");
        // 定义输出流
        OutputStream output = conn.getOutputStream();
        if (null != soapHeader)
        {
            byte[] b = soapHeader.toString().getBytes("utf-8");
            // 发送soap请求报文
            output.write(b, 0, b.length);
        }
        output.flush();
        output.close();
        // 定义输入流，获取soap响应报文
        InputStream input = conn.getInputStream();
        responseXML = IOUtils.toString(input, "UTF-8");
        input.close();
        return responseXML;
    }

    /**
     * @throws Exception
     * @Title: executeCallWithNoAction
     * @Description:不需要SOAPAction的方式 大部分wsdl均可使用该方式
     * @author CuiZiHua
     * @param soapXML
     * @param httpUrl
     * @return
     * @throws
     */
    private String executeCallWithNoAction(String soapXML, String httpUrl)
            throws Exception
    {
        // 响应soap信息
        String responseXML = new String();
        // 第一步：创建服务地址，不是WSDL地址
        URL url = new URL(httpUrl);
        // 第二步：打开一个通向服务地址的连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 第三步：设置参数
        // 3.1发送方式设置：POST必须大写
        connection.setRequestMethod("POST");
        // 3.2设置数据格式：content-type
        connection.setRequestProperty("content-type", "text/xml;charset=utf-8");
        // 3.3设置输入输出，因为默认新创建的connection没有读写权限，
        connection.setDoInput(true);
        connection.setDoOutput(true);

        // 第四步：组织SOAP数据，发送请求
        soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + soapXML;
        OutputStream os = connection.getOutputStream();
        os.write(soapXML.getBytes("UTF-8"));
        // 第五步：接收服务端响应，打印
        int responseCode = connection.getResponseCode();
        if (200 == responseCode)
        {
        	// 表示服务端响应成功
            InputStream input = connection.getInputStream();
            responseXML = IOUtils.toString(input, "UTF-8");
            // 关闭流
            input.close();
        }
        // 关闭流
        os.close();
        return responseXML;
    }

 // 解析xml并返回所需节点
    public String XMLReader(String sb, String StatusCode)
            throws DocumentException
    {
        Document document = DocumentHelper.parseText(sb);
        Element node = document.getRootElement();
        // 根据节点名称获取节点值
        return listNodes(node, StatusCode);
    }

    private String listNodes(Element node, String StatusCode)
    {

        // 返回值 默认失败
        String value = "";
        // 获取当前节点的所有属性节点
        if (!(node.getTextTrim().equals("")))
        {
            if (node.getName().equals(StatusCode))
            {
                value = node.getStringValue().toString();

            }

        }
        if (value.length() <= 0)
        {
            // 当前节点下面子节点迭代器
            @SuppressWarnings("unchecked")
            Iterator<Element> it = node.elementIterator(); // 遍历
            while (it.hasNext())
            { // 获取某个子节点对象
                Element e = it.next();
                // 对子节点进行遍历
                value = listNodes(e, StatusCode);
                if (value.length() > 0)
                {
                    break;
                }
            }
        }

        return value;

    }

    /**
     * 从指定节点开始,递归遍历所有子节点
     * 
     * @author cuizihua
     * @throws DocumentException
     */
    public ArrayList<HashMap<String, String>> getNodes(String xmlstring)
            throws DocumentException
    {
        ArrayList<HashMap<String, String>> arrayList = new ArrayList<HashMap<String, String>>();

        Document document = DocumentHelper.parseText(xmlstring);
        // 获取根节点
        Element node = document.getRootElement();
        // 根据节点名称获取节点值
        putToMapByElementNode(node, arrayList);
        return arrayList;
    }

    /**
     * @Title: putToMapByElementNode
     * @Description:遍历节点 把名称和属性放在map里
     * @author CuiZiHua
     * @param node
     * @throws
     */
    private void putToMapByElementNode(Element node,
            ArrayList<HashMap<String, String>> arrayList)
    {
        // 获取当前节点的所有属性节点
        if (!(node.getName().equals("")) && !(node.getTextTrim().equals("")))
        {
            HashMap<String, String> hashMap = new HashMap<String, String>();
            // System.out.println("当前节点名称：" + node.getName());// 当前节点名称
            // System.out.println("当前节点的内容：" + node.getTextTrim());// 当前节点内容
            hashMap.put(node.getName(), node.getStringValue().toString());
            List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
            // System.out.println(node.attributes().toString());
            for (Attribute attr : listAttr)
            {// 遍历当前节点的所有属性
                String name = attr.getName();// 属性名称
                String value = attr.getValue();// 属性的值
                hashMap.put(name, value);

                // System.out.println("属性名称：" + name + "属性值：" + value);
            }
            arrayList.add(hashMap);
        }
        // 当前节点下面子节点迭代器
        @SuppressWarnings("unchecked")
        Iterator<Element> it = node.elementIterator(); // 遍历
        while (it.hasNext())
        { // 获取某个子节点对象
            Element e = it.next();
            // 对子节点进行遍历
            putToMapByElementNode(e, arrayList);

        }
    }
}
